#include <iostream>
#include <IStreamCapture.h>
#include <windows.h>
#include <assert.h>
#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>
#include <thread>
#include <atomic>
#pragma comment(lib, "StreamCapture.lib")
#pragma comment(lib, "SDL2.lib")
void* owner = (void*)1;
void* capture = NULL;
void* audioPlay = NULL;
void* resampler = NULL;

void log(int level, const char* log)
{
	printf("%s\n", log);
}

struct Cache
{
	unsigned char* buf;
	int length;

	static const int MAXLEN = 1024 * 1024;
	Cache()
	{
		buf = new unsigned char[MAXLEN];
		length = 0;
	}
	void push(unsigned char* buffer, int len)
	{
		assert(length + len <= MAXLEN);
		memcpy(buf + length, buffer, len);
		length += len;
	}
	void remove(int len)
	{
		assert(length >= len);
		memmove(buf, buf + len, length - len);
		length -= len;
	}
};
Cache _cache;
void audiocb(void *owner, uint8_t *stream, int len)
{
	Cache* cache = &_cache;

	while (cache->length < len)
	{
		Frame* frame = ::TryGrabFrame(capture, FRAME_TYPE_AUDIO);
		if (!frame) continue;
		if (frame->flags == FRAME_FLAG_EOF) break;
		ResampleData* rd = (ResampleData*)Resample(resampler, frame);
		cache->push(rd->data, rd->len);
		::RemoveFrame(capture, FRAME_TYPE_AUDIO);
	}

	int minLen = SCMIN(len, cache->length);

	MixAudioFormat(stream, cache->buf, minLen, 0.5);

	cache->remove(minLen);
}

FILE* fp = NULL;
void audiocb_pcm(void *owner, uint8_t *stream, int len)
{
	char* buffer = new char[len];
	if (fread(buffer, 1, len, fp) != len)
	{
		fseek(fp, 0, SEEK_SET);
		assert(fread(buffer, 1, len, fp) == len);
	}
	memcpy(stream, buffer, len);
	delete buffer;
}
void audioOpenCb(void* owner, AudioPlayParams* param)
{

	fp = fopen("D:/HTTPServer/Faded.pcm", "rb");
	assert(fp);
	StartAudioPlay(audioPlay);
}



//int StreamCaptureTest()
//{
//	InitializeStreamCapture(log);
//	while (true)
//	{
//		capture = ::CreateStreamCapture(owner);
//		::SetOption(capture, OptionType::OT_OpenModel, OPEN_MODEL_URL);
//
//		for (int i = 0; i < 10; i++)
//		{
//			//const char* url = "rtsp://admin:Hikvision1234@192.168.1.10:554/h264/ch1/main/av_stream";
//			const char* url = "D:/HTTPServer/Faded.mp4";
//			//if (argc == 2)
//			//	url = argv[1];
//			StreamsParameters* sp = (StreamsParameters*)::Open(capture, url);
//			if (sp->retcode != RETCODE_SUCCESS)
//				break;
//
//			if (sp->as)
//			{
//				audioPlay = CreateAudioPlay(owner, audiocb);
//				AudioPlayParams* app = OpenAudioPlay(audioPlay, sp->as);
//
//				resampler = CreateResampler();
//				assert(OpenResampler(resampler, sp->as, app->desas) == 0);
//
//				StartAudioPlay(audioPlay);
//			}
//
//			int index = 0;
//			for (;;)
//			{
//				Frame* frame = ::TryGrabFrame(capture, FRAME_TYPE_VIDEO);
//				if (!frame) continue;
//				if (frame->flags == FRAME_FLAG_EOF) break;
//				if (frame->pts > ::GetDuration(capture) * 0.1)
//				{
//					::Seek(capture, 0.05);
//					++index;
//					if (index > 2)
//						break;
//				}
//				::RemoveFrame(capture, FRAME_TYPE_VIDEO);
//				Sleep(35);
//			}
//
//			if (sp->as)
//			{
//				DeleteAudioPlay(audioPlay);
//				DeleteResampler(resampler);
//			}
//		}
//
//
//		Close(capture);
//		DeleteStreamCapture(capture);
//	}
//}



void sdl_callback(void *userdata, Uint8 * stream, int len)
{
	char* buffer = new char[len];
	if (fread(buffer, 1, len, fp) != len)
	{
		fseek(fp, 0, SEEK_SET);
		assert(fread(buffer, 1, len, fp) == len);
	}
	memcpy(stream, buffer, len);
	delete buffer;
}


void openaudioplay_cb(void* owner, AudioPlayParams* app)
{
	StartAudioPlay(audioPlay);
}
void audioplay_cb(void* udata, uint8_t* stream, int len)
{
	unsigned char* buffer = new unsigned char[len];
	if (fread(buffer, 1, len, fp) != len)
	{
		fseek(fp, 0, SEEK_SET);
		assert(fread(buffer, 1, len, fp) == len);
	}
	//memcpy(stream, buffer, len);
	MixAudioFormat(stream, buffer, len, 1.0f);
	delete buffer;
}
void Test3()
{
	AudioStream* ias = new AudioStream();
	ias->channel_layout = 3;
	ias->channels = 2;
	ias->samplerate = 44100;
	ias->samplefmt = 8;
	ias->streamCount = 1;
	fp = fopen("F:/HTTPServer/Faded.pcm", "rb");
	audioPlay = CreateAudioPlay((void*)1);
	for (int i = 0; i < 1000; i++)
	{
		long long t0 = GetTimestampUTC();
		//OpenAudioPlayAsync(audioPlay, ias, openaudioplay_cb, audioplay_cb);
		AudioPlayParams* app = OpenAudioPlay(audioPlay, ias, audioplay_cb);
		StartAudioPlay(audioPlay);
		Sleep(100000);
		CloseAudioPlay(audioPlay);
		//printf("%ld\n", (GetTimestampUTC() - t0));

	}
	DeleteAudioPlay(audioPlay);

	getchar();
}

void TestResampler()
{
	AudioStream* ias = new AudioStream();
	ias->channel_layout = 3;
	ias->channels = 2;
	ias->samplerate = 44100;
	ias->samplefmt = 8;
	ias->streamCount = 1;

	long long t0 = GetTimestampUTC();
	int count = 10000000;
	resampler = CreateResampler();
	for (int i = 0; i < count; i++)
	{
		
		OpenResampler(resampler, ias, ias);
		Sleep(10);
	}
	DeleteResampler(resampler);
	t0 = GetTimestampUTC() - t0;
	float t = (float)t0 / count;
	printf("%lf\n", t);
	
	getchar();
}
int main(int argc, char *argv[])
{
	//testAudioPlay();
	//Test();
	//sdltest();
	//Test3();
	TestResampler();
	return 0;
}